const express = require('express');
const fs = require('fs')
const path = require('path')
const mime = require('./module/mime-type.js')

const app = express();
const PORT = 2580;

// 全局拦截器
app.use((req, res, next) => {
    const startTime = new Date(); // 记录请求开始时间

    // 请求完成后的回调（监听 finish 事件）
    res.on('finish', () => {
        logToFile(req, res, startTime)
    });

    next();
});

const staticOption = {
    // 自定义响应头
    setHeaders: (res, filePath) => {
        // 自动设置正确的 Content-Type
        const contentType = mime.getMimeType(path.extname(filePath));
        if (contentType) {
            res.setHeader('Content-Type', contentType);
        }

        // 支持范围请求（用于视频/音频）
        if (contentType?.startsWith('video/') || contentType?.startsWith('audio/')) {
            res.setHeader('Accept-Ranges', 'bytes');
        }

        // 缓存控制
        res.setHeader('Cache-Control', 'public, max-age=31536000');
    },

    // 其他选项
    dotfiles: 'ignore', // 忽略点文件
    fallthrough: true, // 允许继续到下一个中间件
    index: false // 禁用目录索引
}

// 静态文件中间件
app.use('/media', express.static('public/media', staticOption));
app.use('/js', express.static('public/js', staticOption));
app.use('/css', express.static('public/css', staticOption));

// 路由示例
app.get('/', (req, res) => {
    // 使用 path.join 确保跨平台兼容性
    const filePath = path.join(__dirname, 'public/index.html');

    res.sendFile(filePath, (err) => {
        if (err) {
            console.error('文件发送失败:', err);
            res.status(404).send('文件未找到');
        }
    });
});

app.get('/api/data', (req, res) => {
    // 运行跨域请求
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.json({
        message: 'This is JSON data'
    });
});

app.get('/api/hello', (req, res, next) => {
    res.send('你好，欢迎使用 Express！\n' +
        '现在是北京时间：' + formatDate(new Date()) + '\n');
});

// 模拟抛出错误
app.get('/error', (req, res, next) => {
    next(new Error('测试错误'));
});

// 错误拦截器（必须放在所有路由之后）
app.use((err, req, res, next) => {
    if (err) {
        console.error(err.stack);
        res.status(500).json({
            error: '服务器内部错误'
        });
    }
});

app.listen(PORT, () => {
    console.log(`Express server running at http://localhost:${PORT}/`);
});


// 写入日志（按天分割，按月归档）
function logToFile(req, res, startTime) {
    let time = new Date();
    const duration = time - startTime;
    time = formatDate(time).replace(/\//g, '-');
    const log =
        `[${time.slice(0, 19)}] ${req.method} ${req.url} ` +
        `| IP: ${req.ip} ` +
        `| Status: ${res.statusCode} ` +
        `| ${duration}ms`;
    console.log(log);

    // 创建月目录（如果不存在）
    const monthDir = path.join(__dirname, 'logs', time.slice(0, 7));
    if (!fs.existsSync(monthDir)) {
        fs.mkdirSync(monthDir, {
            recursive: true
        });
    }

    // 日志文件名（按日期）
    const logFile = path.join(monthDir, time.slice(0, 10) + `.log`);

    // 写入日志
    fs.appendFile(logFile, `${log}\n`, (err) => {
        if (err) console.error('写入日志失败:', err);
    });
}

function formatDate(date) {
    if (!(date instanceof Date)) {
        throw new Error('Invalid date object');
    }
    const formatter = new Intl.DateTimeFormat('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hourCycle: 'h23' // 24小时制
    });
    return formatter.format(date);
}